# coding=utf-8
import json

from rest_framework import serializers

from social.account.models import User
from social.exceptions import PhoneFormatInvalidException, CodeException
from social.im.api import ZIMAPI
from social.im.tasks import send_system_text_message
from social.token.models import Token
from social.user.serializers import UserSerializer
from social.user.tasks import check_user_avatar
from social.utils import validator
from social.utils.one_key_login import OneKeyLogin
from social.utils.serializers import HashidField, CityNameField
from social.utils.shortcut import get_object_or_none
from social.utils.sms import SMSAuth
from social.utils.upload_path import strip_image_path


class UserLoginSerializer(serializers.ModelSerializer):
    id = HashidField(model=User)
    phone = serializers.CharField(required=False)
    password = serializers.CharField(required=False, write_only=True)
    code = serializers.CharField(required=False, write_only=True)
    token = serializers.CharField(required=False, write_only=True)

    def __init__(self, **kwargs):
        super(UserLoginSerializer, self).__init__(**kwargs)
        self.login_type = None

    def create(self, validated_data):
        phone = validated_data.get('phone')
        code = validated_data.get('code')
        password = validated_data.get('password')
        token = validated_data.get('token')
        request = self.context.get('request')
        user = None
        if password:
            # 密码登录
            user = get_object_or_none(User, phone=phone)
            if not user or not user.check_password:
                raise CodeException(msg='账号或密码错误')
        elif code:
            # 验证码登录
            if request and request.ua.other.channel == 'admin':
                code = '12345678'
            sms_auth = SMSAuth(usage=SMSAuth.LOGIN)
            if sms_auth.is_authed(phone_code=86, phone_number=phone, auth_code=code):
                user = get_object_or_none(User, phone=phone)
        elif token:
            phone = OneKeyLogin.get_mobile(token)
            user = get_object_or_none(User, phone=phone)
        else:
            raise CodeException(msg='登录异常，请稍后再试')
        if not user:
            user = User.objects.create(phone=phone, phone_code=86, username=f'86{phone}')
            ZIMAPI().create_user([{'UserId': user.im_id, 'UserName': f'用户{user.uid}'}])
            send_system_text_message.delay(user.im_id, '恭喜您，注册成功，欢迎您的到来！')
        return user

    def to_representation(self, instance):
        data = UserSerializer(instance).data
        token, created = Token.objects.get_or_create(user=instance)
        if not created:
            token.update_token()
        data['auth_token'] = token.key
        return data

    class Meta:
        model = User
        fields = ('id', 'phone', 'password', 'code', "token")


class UserUpdateSerializer(serializers.ModelSerializer):
    nickname = serializers.CharField(required=False, trim_whitespace=False)
    gender = serializers.CharField(required=False)
    height = serializers.IntegerField(required=False)
    weight = serializers.IntegerField(required=False)
    role = serializers.CharField(required=False)
    birthday = serializers.DateField(format='%Y-%m-%d', required=False)
    job = serializers.CharField(required=False)
    hide_last_active = serializers.BooleanField(required=False)
    hide_location = serializers.BooleanField(required=False)
    city = serializers.CharField(required=False, write_only=True)
    city_name = CityNameField(source='city')
    relationship = serializers.IntegerField(required=False)
    photos = serializers.ListField(required=True)

    def update(self, instance, validated_data):
        keys = set(validated_data.keys())
        photos_change = False
        old_avatar = instance.avatar.name if instance.avatar else ''
        if 'photos' in keys:
            photos = list(validated_data.get('photos'))
            photos = list(map(lambda x: strip_image_path(x), photos))
            validated_data['avatar'] = photos[0]
            validated_data['photos'] = str(json.dumps(photos))
            photos_change = True

        data = super(UserUpdateSerializer, self).update(instance, validated_data)
        new_avatar = data.avatar.name
        if old_avatar != new_avatar and photos_change:
            check_user_avatar.delay(instance.id)
        return data

    def validated_hide_last_active(self, hide_last_active):
        request = self.context.get('request')
        user = request.user
        if not user.is_vip and hide_last_active:
            raise CodeException(msg='您还不是vip,无法隐藏活跃时间')
        return hide_last_active

    def to_representation(self, instance):
        data = UserSerializer(instance).data
        return data

    class Meta:
        model = User
        fields = (
            'nickname', 'gender', 'height', 'weight', 'birthday', 'job', 'city', 'city_name', 'bio', 'relationship',
            'photos', 'role', 'hide_last_active', 'hide_location'
        )


class AuthCodeSerializer(serializers.Serializer):
    """
    验证码
    """
    phone = serializers.CharField(max_length=11, min_length=11)

    def validate_phone(self, value):
        if value and validator.is_phone_cn(value):
            return value
        raise PhoneFormatInvalidException()
